package cn.com.huzo.service.purchase.impl;

import cn.com.huzo.model.entities.purchase.NotesPayabledLinesPoStockInEntity;
import cn.com.huzo.repository.purchase.NotesPayabledLinesRepository;
import cn.com.huzo.service.purchase.NotesPayabledLinesManager;
import huzofw.service.impl.GenericManagerImpl;
import java.util.Date;
import java.util.Calendar;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.annotation.Resource;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import huzofw.model.entities.paginator.Paginator;
import org.apache.commons.collections4.MapUtils;
import cn.com.huzo.repository.purchase.NotesPayabledLinesPoStockInRepository;
import cn.com.huzo.service.purchase.NotesPayabledLinesPoStockInManager;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;

/**
 * 对账单-明细（到货情况）管理服务对象类实现。
 *
 * @author 吴旭
 */
@Service("NotesPayabledLinesPoStockInManager")
public class NotesPayabledLinesPoStockInManagerImpl extends GenericManagerImpl<NotesPayabledLinesPoStockInEntity, String>
        implements NotesPayabledLinesPoStockInManager {

    @Resource(name = "NotesPayabledLinesPoStockInRepository")
    private NotesPayabledLinesPoStockInRepository _dao_lines_po_stockin;

    @Resource(name = "NotesPayabledLinesRepository")
    private NotesPayabledLinesRepository _dao_lines;

    @Resource(name = "NotesPayabledLinesManager")
    private NotesPayabledLinesManager _manager_lines;

    /**
     * {@inheritDoc}
     *
     * @throws java.lang.Exception
     */
    @Override
    @Transactional
    public List<NotesPayabledLinesPoStockInEntity> fetchByHeaderKey(Map<String, Object> criterion) throws Exception {
        return _dao_lines_po_stockin.fetchByHeaderKey(criterion);
    }

    /**
     * {@inheritDoc}
     *
     * @throws java.lang.Exception
     */
    @Transactional
    @Override
    public Map<String, Object> fetchAccountPayableForPage(Map<String, Object> criterion) throws Exception {
        Map<String, Object> _result = new HashMap();

        // 第一步：寻找符合条件的采购订单，根据对账周期和供应商，检查到货数是否满足  组料单的补给数，如果满足则可以对帐，
        // 否则不能正常对账，但是可以强制对账
        List<NotesPayabledLinesPoStockInEntity> accountPayableList = _dao_lines_po_stockin.fetchAccountPayable(criterion);  // 返回poId+stockInheaderId的列表
        if (!accountPayableList.isEmpty()) {
            //第二步：提取可进行对账的入库单记录
            Long offset = (long) ((Integer) criterion.get("Limit")) * (((Integer) criterion.get("PageIndex")) - 1);
            criterion.put("Offset", offset);
            criterion.put("AccountPayableList", accountPayableList);
            List<NotesPayabledLinesPoStockInEntity> itemList = _dao_lines_po_stockin.fetchForPage(criterion);
            long total = _dao_lines_po_stockin.fetchForCount(criterion);
            Paginator<NotesPayabledLinesPoStockInEntity> paginator = new Paginator<>(itemList, offset, (Integer) criterion.get("Limit"), total);

            _result.put("TotalRecordCount", paginator.getTotal());
            _result.put("TotalPages", paginator.getTotalPages());
            _result.put("PageIndex", paginator.getPageIndex());
            _result.put("DataList", paginator.getItemList());
            _result.put("Success", true);
        } else {
            _result.put("Success", false);
        }

        return _result;
    }

    /**
     * {@inheritDoc}
     *
     * @throws java.lang.Exception
     */
    @Transactional
    @Override
    public Map<String, Object> add(Map<String, Object> criterion) throws Exception {
        ObjectMapper mapper = new ObjectMapper();
        List<Long> _stockInHeaderIdList = mapper.convertValue(MapUtils.getObject(criterion, "StockInIdList"), new TypeReference<List<Long>>() {
        });
        
        // 插入对账用到货情况
        Map<String, Object> params = new HashMap();
        params.put("HeaderId", MapUtils.getLong(criterion, "HeaderId"));
        params.put("Flag", MapUtils.getLong(criterion, "Flag"));
        params.put("StockInHeaderIdList", _stockInHeaderIdList);
        params.put("CreatedBy", MapUtils.getLong(criterion, "CreatedBy"));
        params.put("UpdatedBy", MapUtils.getLong(criterion, "UpdatedBy"));
        _dao_lines_po_stockin.insert(params);
        //插入明细记录
        _dao_lines.insert(params);

        Map<String, Object> _result = new HashMap();
        //到货列表
        _result.put("LinesPoStockInList", _dao_lines_po_stockin.fetchByHeaderKey(criterion));
        //对账明细表 
        _result.put("LinesData", _manager_lines.fetchForPage(criterion));
        // 本次对账总金额
        _result.put("TotalAmount", _dao_lines.fetchTotalAmount(criterion));

        return _result;
    }

    /**
     * {@inheritDoc}
     *
     * @throws java.lang.Exception
     */
    @Transactional
    @Override
    public Map<String, Object> delete(Map<String, Object> criterion) throws Exception {
        // 删除该到货数据对应的对账明细
        _dao_lines.deleteByPoStackInLinesId(MapUtils.getString(criterion, "LinesId"));
        // 删除到货
        _dao_lines_po_stockin.delete(MapUtils.getString(criterion, "LinesId"));

        Map<String, Object> _result = new HashMap();
        //到货列表
        _result.put("LinesPoStockInList", _dao_lines_po_stockin.fetchByHeaderKey(criterion));
        //对账明细表       
        _result.put("LinesData", _manager_lines.fetchForPage(criterion));
        // 本次对账总金额
        _result.put("TotalAmount", _dao_lines.fetchTotalAmount(criterion));

        return _result;
    }

    /**
     * {@inheritDoc}
     *
     * @throws java.lang.Exception
     */
    @Transactional
    @Override
    public Map<String, Object> batchDeleteLines(Long headerId, Long deletedBy, Integer limit02, String orderBy,
            List<NotesPayabledLinesPoStockInEntity> itemList) throws Exception {
        Map<String, Object> _result = new HashMap();

        // 删除到货记录对应的对账明细
        for (int i = 0; i < itemList.size(); i++) {
            _dao_lines.deleteByPoStackInLinesId(itemList.get(i).getLinesId());
        }
        // 删除到货情况记录
        _dao_lines_po_stockin.batchDelete(itemList);

        Map<String, Object> criterion = new HashMap();
        criterion.put("HeaderId", headerId);
        // 到货列表
        _result.put("LinesPoStockInList", _dao_lines_po_stockin.fetchByHeaderKey(criterion));
        // 对账明细表
        criterion.put("PageIndex", 1);  // 当前明细页
        criterion.put("Limit", limit02);
        criterion.put("OrderBy", orderBy);
        _result.put("LinesData", _manager_lines.fetchForPage(criterion));
        // 本次对账总金额
        _result.put("TotalAmount", _dao_lines.fetchTotalAmount(criterion));
        _result.put("Success", true);

        return _result;
    }

    /**
     * 在日期上增加数个整月
     *
     * @param date
     * @param n
     * @return
     */
    private Date addMonth(Date date, int n) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.add(Calendar.MONTH, n);
        return cal.getTime();
    }
}
